/*************************************************
 * 
 * Copyright by Bruno Eberhard
 * 
 * Created on 01.08.2005
 *
 *************************************************/
package fightplan.algorithmen.ko;

import java.util.ArrayList;
import java.util.List;

import fightplan.algorithmen.Layout;
import fightplan.algorithmen.LayoutFactory;
import fightplan.algorithmen.ko.KOPanel.WinMouseListener;
import fightplan.business.Fight;
import fightplan.business.FighterHolder;
import fightplan.business.Plan;

public class KOLayoutFactory implements LayoutFactory {

	private int sheetDepth = 4;

	private int minSheets = 2;

	public Layout layout(Plan plan, boolean min2Sheets) {
		minSheets = min2Sheets ? 2 : 1;
		KOPlan koPlan = (KOPlan) plan;
		KOLayout layout = new KOLayout();

		List<Fight> rootFights = splitInSheets(koPlan);
		int count = 0;
		if (rootFights.size() > 1) {
			for (Fight rootFight : rootFights) {
				if (count == 0) {
					KOPanel koPanel = new KOPanel(rootFight, sheetDepth, null, koPlan.getUpperTrostRundeFights());
					layout.getPanels().add(koPanel);
					layout.setFightLocation(rootFight, koPanel);
					layout.setFightLocation(koPlan.getUpperTrostRundeFights(), koPanel);
				} else if (count < rootFights.size() - 1) {
					KOPanel koPanel = new KOPanel(rootFight, sheetDepth);
					layout.getPanels().add(koPanel);
					layout.setFightLocation(rootFight, koPanel);
				} else {
					KOPanel koPanel = new KOPanel(rootFight, sheetDepth, null, koPlan.getLowerTrostRundeFights());
					layout.getPanels().add(koPanel);
					layout.setFightLocation(rootFight, koPanel);
					layout.setFightLocation(koPlan.getLowerTrostRundeFights(), koPanel);
				}
				count++;
			}
			int endDepth = 0;
			int panelCount = layout.getPanels().size();
			while (panelCount > 1) {
				endDepth++;
				panelCount /= 2;
			}
			;

			// CR 14: Keine Wiederholung der Trostunde auf dem Finalblatt
			// KOPanel endPanel = new KOPanel(koPlan.getRootFight(), endDepth,
			// koPlan.getUpperTrostRundeFights(),
			// koPlan.getLowerTrostRundeFights());

			boolean doEndPanel = true;
			if (plan instanceof FinalrundePlan && count == 2)
				doEndPanel = false;

			if (doEndPanel) {
				KOPanel endPanel = new KOPanel(koPlan.getRootFight(), endDepth, plan instanceof FinalrundePlan);
				endPanel.setEndPanel(true);
				layout.setEndSheet(endPanel);
				layout.setFightLocation(koPlan.getRootFight(), endPanel);
			}
		} else {
			KOPanel koPanel = new KOPanel(rootFights.get(0), sheetDepth, koPlan.getUpperTrostRundeFights(),
					koPlan.getLowerTrostRundeFights());
			layout.getPanels().add(koPanel);
			layout.setFightLocation(rootFights.get(0), koPanel);
		}
		if (rootFights.size() == 2) {
			Fight rootFight = koPlan.getRootFight();
			layout.getPanels().get(0).getRootLabel()
					.addMouseListener(new WinMouseListener(rootFight, rootFight.getFightEntries().get(0)));
			layout.getPanels().get(1).getRootLabel()
					.addMouseListener(new WinMouseListener(rootFight, rootFight.getFightEntries().get(1)));
		}

		if (plan instanceof FinalrundePlan) {
			layout.setFinalrundeSheet(new FinalrundePanel(koPlan.getRootFight()));
		}

		return layout;
	}

	// layouting

	private List<Fight> splitInSheets(KOPlan plan) {
		// split in sheets
		int depth = plan.calcDepth(plan.getRootFight());

		List<Fight> rootFights = new ArrayList<Fight>();
		rootFights.add(plan.getRootFight());

		while (depth > sheetDepth || rootFights.size() < minSheets) {
			List<Fight> newRootFights = new ArrayList<Fight>();
			for (Fight rootFight : rootFights) {
				newRootFights.add(((FighterHolder) rootFight.getFightEntries().get(0).getFighterProvider()).getFight());
				newRootFights.add(((FighterHolder) rootFight.getFightEntries().get(1).getFighterProvider()).getFight());
			}
			rootFights = newRootFights;
			depth = depth - 1;
		}

		return rootFights;
	}

}
